﻿using Abp.Configuration.Startup;
using Abp.Dependency;
using Abp.MailKit;
using Abp.Modules;
using Abp.Net.Mail;
using Abp.Net.Mail.Smtp;
using Abp.Reflection.Extensions;
using Abp.Web.Configuration;
using Abp.Zero.Configuration;
using Castle.MicroKernel.Registration;
using MailKit.Security;
using Mt.Site.Core.AccessStatistics.Features;
using Mt.Site.Core.AccessStatistics.Permissions;
using Mt.Site.Core.Base.Web;
using Mt.Site.Core.Configuration;
using Mt.Site.Core.ContentManagement.Features;
using Mt.Site.Core.ContentManagement.Permissions;
using Mt.Site.Core.DataLogs.Features;
using Mt.Site.Core.DataLogs.Permissions;
using Mt.Site.Core.Debugging;
using Mt.Site.Core.DynamicEntityParameters;
using Mt.Site.Core.EntityHistory;
using Mt.Site.Core.Friendships.Cache;
using Mt.Site.Core.Localization;
using Mt.Site.Core.Members.Features;
using Mt.Site.Core.Members.Permissions;
using Mt.Site.Core.Messages_.Features;
using Mt.Site.Core.Messages_.Permissions;
using Mt.Site.Core.Navigation;
using Mt.Site.Core.Navigations.Modules;
using Mt.Site.Core.Navigations.Navigation;
using Mt.Site.Core.Net.Emailing;
using Mt.Site.Core.Organizations;
using Mt.Site.Core.SiteMaps;
using Mt.Site.Core.Taxonomys.Permissions;
using Mt.Site.Core.Url;
using Mt.Site.Core.Webhooks;
using Mt.Site.Core.WorkFlows;
using Mt.Site.Core.WorkFlows.Diy;
using Mt.Site.Core.WorkFlows.Diy.Actions.Impl;
using Mt.Site.Core.WorkFlows.Diy.Plugin.Impl;
using Mt.Site.Core.WorkFlows.Diy.Plugin.Impl.tougao;
using Mt.Site.Core.WorkFlows.Diy.Plugin.Impl.yglh;
using Mt.Site.Core.WorkFlows.Features;
using Mt.Site.Core.WorkFlows.Permissions;
using System;

namespace Mt.Site.Core
{
    [DependsOn(
    typeof(MtSiteCoreBaseModule))]
    public class MtSiteCoreModule : AbpModule
    {
        public override void PreInitialize()
        {
            //Enable LDAP authentication (It can be enabled only if MultiTenancy is disabled!)
            //Configuration.Modules.ZeroLdap().Enable(typeof(AppLdapAuthenticationSource));

            MtSiteLocalizationExConfigurer.Configure(Configuration.Localization);
            Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();

            AddingAuthorizationProviders();
            AddingFeatureProviders();
            AddingSettingProviders();
            AddingNotificationProviders();

            //Adding webhook definition providers
            Configuration.Webhooks.Providers.Add<AppWebhookDefinitionProvider>();
            Configuration.Webhooks.TimeoutDuration = TimeSpan.FromMinutes(1);
            Configuration.Webhooks.IsAutomaticSubscriptionDeactivationEnabled = false;

            //Adding DynamicEntityParameters definition providers
            Configuration.DynamicEntityProperties.Providers.Add<AppDynamicEntityPropertyDefinitionProvider>();

            Configuration.ReplaceService<IGlobalizationHelper, MtGlobalizationHelper>(DependencyLifeStyle.Singleton);


            //Twilio - Enable this line to activate Twilio SMS integration
            //Configuration.ReplaceService<ISmsSender,TwilioSmsSender>();

            // MailKit configuration
            Configuration.Modules.AbpMailKit().SecureSocketOption = SecureSocketOptions.Auto;
            Configuration.ReplaceService<IMailKitSmtpBuilder, MtSiteMailKitSmtpBuilder>(DependencyLifeStyle.Transient);

            if (DebugHelper.IsDebug)
            {
                //Disabling email sending in debug mode
                Configuration.ReplaceService<IEmailSender, NullEmailSender>(DependencyLifeStyle.Transient);
            }
            Configuration.ReplaceService(typeof(IEmailSenderConfiguration), () =>
            {
                Configuration.IocManager.IocContainer.Register(
                    Component.For<IEmailSenderConfiguration, ISmtpEmailSenderConfiguration>()
                             .ImplementedBy<MtSiteSmtpEmailSenderConfiguration>()
                             .LifestyleTransient()
                );
            });

            SetCacheSlidingExpireTime();

            Configuration.Navigation.Providers.Add<BackEndSystemPlusProvider>();

            Configuration.CustomConfigProviders.Add(new CustomConfigProvider());
            Configuration.CustomConfigProviders.Add(new EntityHistoryConfigProvider(Configuration));
            Configuration.ReplaceService<ICustomConfigScriptManager, OaCustomConfigScriptManager>(DependencyLifeStyle.Transient);
            Configuration.ReplaceService<AbpUserConfigurationBuilder, MUserConfigurationBuilder>(DependencyLifeStyle.Transient);

            Configuration.ReplaceService<IUrlGetter, NewUrlGetter>(DependencyLifeStyle.Transient);
            
            AddingWorkFlowConfiguration();
        }

        private void SetCacheSlidingExpireTime()
        {
            //Configuration.Caching.ConfigureAll(cache =>
            //{
            //    cache.DefaultSlidingExpireTime = TimeSpan.FromMinutes(30);
            //});

            Configuration.Caching.Configure(FriendCacheItem.CacheName, cache =>
            {
                cache.DefaultSlidingExpireTime = TimeSpan.FromMinutes(30);
            });
        }

        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(typeof(MtSiteCoreModule).GetAssembly());
            //站内短消息同时发短信
            //Configuration.Notifications.Notifiers.Add<SmsRealTimeNotifier>();
        }

        public override void PostInitialize()
        {
            var moduleProvider = IocManager.Resolve<IModuleProvider>();

            moduleProvider.ModuleDefinitions.Add(
                ContentPermissionProvider.ModuleName,
                new ModuleDefinition
                {
                    Name = ContentPermissionProvider.ModuleName,
                    DisplayName = "内容模块",
                    Features = new FeaturesParam(new string[] { ContentFeatures.ContentFeature }, true)
                });

            moduleProvider.ModuleDefinitions.Add(
                ContentPermissionProvider.ModuleName2,
                new ModuleDefinition
                {
                    Name = ContentPermissionProvider.ModuleName2,
                    DisplayName = "内容模块2",
                    Features = new FeaturesParam(new string[] { ContentFeatures.ContentFeature }, true)
                });

            moduleProvider.ModuleDefinitions.Add(
                MessagesPermissionProvider.ModuleName,
                new ModuleDefinition
                {
                    Name = MessagesPermissionProvider.ModuleName,
                    DisplayName = "留言模块",
                    Features = new FeaturesParam(new string[] { MessagesFeatures.MessagesFeature }, true)
                });
        }


        #region 各种Providers
        private void AddingWorkFlowConfiguration()
        {
            IocManager.Register(typeof(IWorkFlowPluginConfiguration), typeof(WorkFlowPluginConfiguration), DependencyLifeStyle.Singleton);
            var workFlowConfig = IocManager.Resolve<IWorkFlowPluginConfiguration>();

            workFlowConfig.ActionProviders.Add<SubmitAction>(WorkFlowConst.OperationName.SubmitAction);
            workFlowConfig.ActionProviders.Add<BranchLineAction>(WorkFlowConst.OperationName.BranchLineActionName);
            workFlowConfig.ActionProviders.Add<WithdrawAction>(WorkFlowConst.OperationName.WithdrawActionName);
            workFlowConfig.ActionProviders.Add<TransferAction>(WorkFlowConst.OperationName.TransferActionName);
            workFlowConfig.ActionProviders.Add<FinishedAction>(WorkFlowConst.OperationName.FinishedActionName);
            workFlowConfig.ActionProviders.Add<GuiDangAction>(WorkFlowConst.OperationName.GuiDangAction);
            workFlowConfig.ActionProviders.Add<NotAgreeAction>(WorkFlowConst.OperationName.NotAgreeAction);
            workFlowConfig.ActionProviders.Add<MenuPickingAction>(WorkFlowConst.OperationName.MenuPickingAction);

            workFlowConfig.WorkFlowPluginProviders.Add<TougaoPlugin>(TougaoPlugin.Name);

            workFlowConfig.WorkFlowNodePluginProviders.Add<SkipUnitHeaderNode>(SkipUnitHeaderNode.Name);
            workFlowConfig.WorkFlowNodePluginProviders.Add<AutoSubmitNode>(AutoSubmitNode.Name);

            workFlowConfig.WorkFlowNodePluginProviders.Add<TougaoDengjiNode>(TougaoDengjiNode.Name);
            workFlowConfig.WorkFlowNodePluginProviders.Add<TougaoShenheNode>(TougaoShenheNode.Name);
        }
        private void AddingAuthorizationProviders()
        {
            Configuration.Authorization.Providers.Add<TaxonomyPermissionProvider>();
            Configuration.Authorization.Providers.Add<PostPermissionsProvider>();

            Configuration.Authorization.Providers.Add<MemberPermissionProvider>();
            Configuration.Authorization.Providers.Add<MessagesPermissionProvider>();
            Configuration.Authorization.Providers.Add<DataLogsPermissionProvider>();
            Configuration.Authorization.Providers.Add<ContentPermissionProvider>();
            Configuration.Authorization.Providers.Add<ASPermissionProvider>();

            Configuration.Authorization.Providers.Add<SiteMapPermissionProvider>();
            Configuration.Authorization.Providers.Add<WorkFlowPermissionProvider>();
    
        }

        private void AddingFeatureProviders()
        {
            Configuration.Features.Providers.Add<MemberFeatureProvider>();
            Configuration.Features.Providers.Add<MessagesFeatureProvider>();
            Configuration.Features.Providers.Add<DataLogsFeatureProvider>();
            Configuration.Features.Providers.Add<ContentFeatureProvider>();
            Configuration.Features.Providers.Add<ASFeatureProvider>();
            Configuration.Features.Providers.Add<WorkFlowFeatureProvider>();
        }

        private void AddingSettingProviders()
        {
            Configuration.Settings.Providers.Add<MtAppSettingProvider>();
        }

        private void AddingNotificationProviders()
        {
        }

        #endregion
    }
}
